#include "networkserver.h"

#define DEBUG 1

NetworkServer::NetworkServer(QObject *parent, DatabaseInterface *db) :
    QTcpServer(parent)
{
}

void NetworkServer::start()
{
#if DEBUG==1
    qDebug() << "Starting server.";
#endif
    QHostAddress *ipAddress = 0;

    QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
    // use the first non-localhost IPv4 address
    for (int i = 0; i < ipAddressesList.size(); ++i) {
        if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
            ipAddressesList.at(i).toIPv4Address()) {
            ipAddress = new QHostAddress(ipAddressesList.at(i));
            break;
        }
    }
    // if we did not find one, use IPv4 localhost
    if (!ipAddress)
    {
#if DEBUG==1
        qDebug() << "No IPv6 address available, using IPv4 address";
#endif
        ipAddress = new QHostAddress(QHostAddress::LocalHost);
    }

    //listen(QHostAddress::Any, 0);
    emit listeningAt(ipAddress, this->serverPort());
    qWarning() << "Listening on IP address " << ipAddress->toString()
               << "port " << QString::number(this->serverPort()).toLatin1() << ". \n";
}

void NetworkServer::incomingConnection(int socketDescriptor)
{
#if DEBUG==1
    qDebug() << "Incoming connection detected.";
#endif
    QThread *thread = new QThread(this);
    qDebug() << "Starting thread...";
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));

    QSslSocket *socket = new QSslSocket();
    socket->setSocketDescriptor(socketDescriptor);

    Connection *conn = new Connection(0, socket);

    connect(thread, SIGNAL(started()), conn, SLOT(setupComms()));
    connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)),
            conn, SLOT(sslErrors(const QList<QSslError> &)));
    connect(conn, SIGNAL(disconnected()), thread, SLOT(quit()));

    connect(thread, SIGNAL(finished()), socket, SLOT(deleteLater()));
    connect(thread, SIGNAL(finished()), conn, SLOT(deleteLater()));

    socket->moveToThread(thread);
    conn->moveToThread(thread);

    thread->start();
}
